﻿#region File Description
//-----------------------------------------------------------------------------
// SpherePrimitive.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace TangoGames.Primitives3D
{
    /// <summary>
    /// Geometric primitive class for drawing spheres.
    /// </summary>
    public class CubePrimitive : GeometricPrimitive
    {
        /// <summary>
        /// Constructs a new sphere primitive, using default settings.
        /// </summary>
        public CubePrimitive(GraphicsDevice graphicsDevice)
            : this(graphicsDevice, 1, 1 , 1)
        {
        }


        /// <summary>
        /// Constructs a new sphere primitive,
        /// with the specified size and tessellation level.
        /// </summary>
        public CubePrimitive(GraphicsDevice graphicsDevice,
                               float width, float heigth , float length)
        {
            Vector3[] refs = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right, Vector3.Forward, Vector3.Backward };
            foreach (Vector3 v in refs) BuildFace(v, new Vector3(width, heigth, length));
            InitializePrimitive(graphicsDevice);
        }

        private void BuildFace(Vector3 reference, Vector3 dimentions)
        {
            if (reference.X != 0)
            {
                AddFaceX (reference.X * (dimentions.X / 2) ,  -dimentions.Y / 2 ,  dimentions.Z / 2 , reference);
            }
            else if (reference.Y !=0)
            {
                AddFaceY(dimentions.X / 2, reference.Y * (dimentions.Y / 2), dimentions.Z / 2, reference);
            }
            else if (reference.Z !=0)
            {
                AddFaceZ(dimentions.X / 2, -dimentions.Y / 2, reference.Z * (dimentions.Z / 2), reference);
            }
        }

        private void AddFaceX(float X, float Y, float Z, Vector3 reference)
        { 
            AddVertex(new Vector3( X , -Y , -Z ), reference);
            AddVertex(new Vector3( X ,  Y , -Z ), reference);
            AddVertex(new Vector3( X ,  Y ,  Z ), reference);
            AddFaceIndices((int)reference.X);

            AddVertex(new Vector3( X ,  Y ,  Z ), reference);
            AddVertex(new Vector3( X , -Y ,  Z ), reference);
            AddVertex(new Vector3( X , -Y , -Z ), reference);
            AddFaceIndices((int)reference.X);

        }

        private void AddFaceY(float X, float Y, float Z, Vector3 reference)
        {
            AddVertex(new Vector3(-X, Y, -Z), reference);
            AddVertex(new Vector3( X, Y, -Z), reference);
            AddVertex(new Vector3( X, Y,  Z), reference);
            AddFaceIndices((int)reference.Y);

            AddVertex(new Vector3(  X , Y,  Z), reference);
            AddVertex(new Vector3( -X , Y,  Z), reference);
            AddVertex(new Vector3( -X , Y, -Z), reference);
            AddFaceIndices((int)reference.Y);

        }

        private void AddFaceZ(float X, float Y, float Z, Vector3 reference)
        {
            AddVertex(new Vector3(-X, -Y, Z), reference);
            AddVertex(new Vector3(-X,  Y, Z), reference);
            AddVertex(new Vector3( X,  Y, Z), reference);
            AddFaceIndices(-(int)reference.Z);

            AddVertex(new Vector3( X,  Y,  Z), reference);
            AddVertex(new Vector3( X, -Y,  Z), reference);
            AddVertex(new Vector3(-X, -Y,  Z), reference);
            AddFaceIndices(-(int)reference.Z);
        }

        private void AddFaceIndices(int face)
        {
            if (face > 0)
            {
                AddIndex(CurrentVertex - 3);
                AddIndex(CurrentVertex - 2);
                AddIndex(CurrentVertex - 1);
            }
            else
            {
                AddIndex(CurrentVertex - 1);
                AddIndex(CurrentVertex - 2);
                AddIndex(CurrentVertex - 3);
            }

        }
    }
}
